CloucdflareのTiered Cache(階層型キャッシュ)を有効にしてキャッシュヒット率を高めてみた
CDNを活用する上では、キャッシュヒット率を高く保つことが大事です。 キャッシュヒット率が高くなるほど、オリジンへのアクセスが減り、オリジンの負荷やトラフィックを軽減できるからです。
キャッシュヒット率を高めるアプローチの一つが、キャッシュの階層化です。
今回は、Cloudflare CDNのTiered Cacheを用い、キャッシュを階層化してキャッシュヒット率を高める方法を紹介します。
キャッシュの階層化
Cloudflare の CDN は、デフォルトでは、キャッシュは各地のデータセンターで個別に管理され、キャッシュミス時には各DCがオリジンと通信します。 Tiered Cacheを用いると、 オリジンに最寄りのデータセンターをupper-tierとして選出し、このDCだけがオリジンと通信できるようにし、upper-tierと他のtlower-tierのDC間でキャッシュが階層化されます。
※ 図はIntroducing: Smarter Tiered Cache Topology Generation から引用
このようにキャッシュを階層化することで、lower-tier でキャッシュミスした時はupper-tierにコンテンツを問い合わせ、upper-tierにもキャッシュが存在しない場合のみ、オリジンに問い合わせます。 lower-tierの各DCが直接オリジンと通信しなくなるため、オリジンへのリクエストやオリジンとのトラフィックを抑制できます。
キャッシュの階層化を有効にするには、管理コンソールの Caching -> Tiered Cache から「Argo Tiered Cache」を有効にします。
やってみた
Tiered Cacheを利用する前・後のキャッシュ管理の違いを確認します。
AWS東京リージョンにあるオリジンに対して、AWS CloudShellを利用して、世界各地からアクセスしてみます。
Cloudflare Instant Logsで取得したHTTPリクエストログとオリジンのアクセスを突き合わせます。
主要フィールドの意味を確認します。
Field | Value |
---|---|
CacheCacheStatus | miss/hit/stale/dynamicなどのキャッシュステータス |
CacheTieredFill | リクエスト時にTiered Cacheのキャッシュが利用された場合はこのフラグが立つ |
EdgeServerIP | オリジンにリクエストをするエッジサーバーのIP。空の場合はオリジンへのリクエストが発生せず。 |
EdgeTimeToFirstByteMs | ビューアーとCloudflareエッジ間のTTFB |
OriginIP | オリジンサーバーのIPアドレス |
OriginResponseDurationMs | Cloudflareエッジ-オリジン間のTTFB。オリジンへの接続からレスポンスを受け取るまでの時間 |
OriginResponseHeaderReceiveDurationMs | オリジンサーバーの処理時間。オリジンへの接続後にレスポンスを受け取るまでの時間 |
UpperTierColoID | Tiered Cacheで利用された upper tierのデータセンター |
Tiered Cacheを利用しない場合
まずは、「Argo Tiered Cache」が OFF のデフォルトの挙動を確認します。
ヨーロッパから日本オリジンにアクセス
オリジンのある日本から遠く離れたドイツ・フランクフルトからアクセスします。
$ curl -s -D - https://example.com/test.json HTTP/2 200 date: Tue, 24 May 2022 09:29:27 GMT content-type: application/json content-length: 17 x-amzn-requestid: 355ca9c7-906b-44a1-bf7a-377cf8d5e3ed x-amzn-trace-id: root=1-628ca577-0a0939734be100a414e41399;sampled=0 cf-cache-status: MISS last-modified: Tue, 24 May 2022 09:29:27 GMT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 710501c5185a90f2-FRA alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400 ...
対応するCloudflareのリクエストログを抜粋します。
- CacheCacheStatus : miss
- CacheTieredFill : false
- EdgeServerIP : 162.158.89.206
- EdgeTimeToFirstByteMs : 1016 ms
- OriginIP : 162.158.89.206
- OriginResponseDurationMs : 954 ms
- OriginResponseHeaderReceiveDurationMs : 256 ms
- UpperTierColoID : 0
初回アクセスのためキャッシュミスし(レスポンスの cf-cache-status: MISS
とリクエストログの CacheCacheStatus : miss
)、オリジンにアクセスします。
ビューアーとCloudflareエッジ間のTTFB の EdgeTimeToFirstByteMs
は 1016 ms でした。
オリジンサーバーの処理時間(OriginResponseHeaderReceiveDurationMs
) は 256 ms と比較的短いのに対して、エッジからオリジンへの接続も含めた処理時間(OriginResponseDurationMs
)は954msとはるかに大きな値になっています。
エッジ(ドイツ)とオリジン(日本)が遠く離れているのが原因です。
オリジンにリクエストしたソースIPは 162.158.89.206 でした。
これは、CloudflareのフランクフルトにあるのDCのIPアドレスです。
https://whatismyipaddress.com/ip/162.158.89.206
時間をおいて、もう一度アクセスすると、キャッシュヒットしました。
HTTP/2 200 date: Tue, 24 May 2022 09:30:42 GMT content-type: application/json content-length: 17 x-amzn-requestid: 355ca9c7-906b-44a1-bf7a-377cf8d5e3ed x-amzn-trace-id: root=1-628ca577-0a0939734be100a414e41399;sampled=0 cf-cache-status: HIT age: 75 last-modified: Tue, 24 May 2022 09:29:27 GMT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 7105039f2b7f9189-FRA alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
- CacheCacheStatus : hit
- CacheTieredFill : false
- EdgeServerIP :
- EdgeTimeToFirstByteMs : 57 ms
- OriginIP :
- OriginResponseDurationMs : 0 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 0
エッジでキャッシュヒットしているため、ビューアーとCloudflareエッジ間のTTFB(EdgeTimeToFirstByteMs
) は 1016 ms から 57 ms へと激減し、オリジンとの通信は発生しないため、関連するフィールドは 0/ブランク です。
ヨーロッパから日本オリジンにアクセス時の、キャッシュ状態別のHTTPレスポンスヘッダーとCloudflareリクエストログを整理します。
日本から日本オリジンにアクセス
続いて、オリジンと同じ東京からアクセスしてみましょう。
ヨーロッパ・日本それぞれ独自にキャッシュ管理され、オリジンへのリクエストも個別に発生します。
HTTP/2 200 date: Tue, 24 May 2022 09:33:41 GMT content-type: application/json content-length: 17 x-amzn-requestid: 09b819c9-70f5-4d41-9eab-b0360b328572 x-amzn-trace-id: root=1-628ca675-0ae275e748757ef6028be0e9;sampled=0 cf-cache-status: MISS last-modified: Tue, 24 May 2022 09:33:41 GMT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 710507fdd8e9af30-NRT alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
- CacheCacheStatus : hit
- CacheTieredFill : false
- ClientIP : 18.183.41.167
- EdgeServerIP : 172.68.118.118
- OriginIP : 54.65.184.103
- EdgeTimeToFirstByteMs : 172 ms
- OriginResponseDurationMs : 80 ms
- OriginResponseHeaderReceiveDurationMs : 73 ms
- UpperTierColoID : 0
初回アクセスのためキャッシュミスし、オリジンにアクセスします。
ビューアーとCloudflareエッジ間のTTFB(EdgeTimeToFirstByteMs
) は 172 ms でした。
アクセス元とオリジンが至近距離にあるため、オリジンサーバーの処理時間(OriginResponseHeaderReceiveDurationMs
: 73ms)とオリジンへの通信も含めた時間(OriginResponseDurationMs
: 80ms)に大きな差はありません。
オリジンにリクエストしたソースIPは 172.68.118.118でした。 これは東京にあるCloudflareのDCのIPアドレスです。
https://whatismyipaddress.com/ip/172.68.118.118
もう一度アクセスすると、キャッシュヒットします。
HTTP/2 200 date: Tue, 24 May 2022 09:35:24 GMT content-type: application/json content-length: 17 x-amzn-requestid: 09b819c9-70f5-4d41-9eab-b0360b328572 x-amzn-trace-id: root=1-628ca675-0ae275e748757ef6028be0e9;sampled=0 cf-cache-status: HIT age: 103 last-modified: Tue, 24 May 2022 09:33:41 GMT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 71050a8438993481-NRT alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
- CacheCacheStatus : hit
- CacheTieredFill : false
- ClientIP : 18.183.41.167
- EdgeServerIP :
- OriginIP :
- EdgeTimeToFirstByteMs : 22 ms
- OriginResponseDurationMs : 0 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 0
エッジでキャッシュヒットするため、EdgeTimeToFirstByteMs
が 172 ms から 22 ms へと更に低下し、オリジンとの通信に関連するフィールドは 0/ブランク です。
Tiered Cacheを利用する場合
次にArgo Tiered Cacheを有効にし、トポロジーには「Smart Tiered Cache Topology」を選択します。
ヨーロッパから日本オリジンにアクセス
オリジンのある日本から遠く離れたドイツ・フランクフルトからアクセスします。
HTTP/2 200 date: Tue, 24 May 2022 12:50:51 GMT content-type: application/json content-length: 18 x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0 last-modified: Tue, 24 May 2022 12:50:51 GMT cf-cache-status: MISS accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 710628cf1ba09a1d-FRA alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
- CacheCacheStatus : miss
- CacheTieredFill : false
- OriginIP : 52.198.171.117
- EdgeServerIP : 172.70.123.15
- EdgeTimeToFirstByteMs : 626 ms
- OriginResponseDurationMs : 533 ms
- OriginResponseHeaderReceiveDurationMs : 301 ms
- UpperTierColoID : 382
初回アクセスのため、キャッシュミスし、オリジンへのアクセスが発生します。
オリジンにアクセスした IP(172.70.123.15) の所有者を確認すると、ビューアーそばのヨーロッパのものでなく、オリジン最寄りの東京にある Cloudflare データセンターのものです。
https://whatismyipaddress.com/ip/172.70.123.15
upper tier としてオリジン最寄りの東京のデータセンターが選出されていることがわかります。
Tiered Cache 利用時にオリジンと通信する upper tier データセンターを表す UpperTierColoID
フィールドは、これまで 0 だったのに対して、今回は 382 が設定されています。
続けてアクセスすると、キャッシュヒットしました。
HTTP/2 200 date: Tue, 24 May 2022 12:51:33 GMT content-type: application/json content-length: 18 x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0 last-modified: Tue, 24 May 2022 12:50:51 GMT cf-cache-status: HIT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 710629d25f7b9bbc-FRA alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
cf-cache-status: HIT
からキャッシュヒットしたことはわかりますが、age
ヘッダーが存在しません。
Instant Logs を確認します。
- CacheCacheStatus : hit
- CacheTieredFill : true
- OriginIP :
- EdgeServerIP :
- EdgeTimeToFirstByteMs : 470 ms
- OriginResponseDurationMs : 219 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 382
CacheCacheStatus : hit
からキャッシュヒットしたことがわかり、CacheTieredFill : true
から、エッジキャッシュミス後にオリジンの手前の upper tier がキャッシュを返したことがわかります。
ヨーロッパから日本への通信が発生しているため、 EdgeTimeToFirstByteMs
が前回の 626 ms から 470 ms へとあまり改善していないのも納得です。
また、キャッシュに利用された UpperTierColoID
が埋まっています。
もう一度リクエストします。
HTTP/2 200 date: Tue, 24 May 2022 12:52:20 GMT content-type: application/json content-length: 18 x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0 last-modified: Tue, 24 May 2022 12:50:51 GMT cf-cache-status: HIT age: 89 accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 71062af8fc656933-FRA alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
今度は age ヘッダーもかえってきました。
- CacheCacheStatus : hit
- CacheTieredFill : false
- OriginIP :
- EdgeServerIP :
- EdgeTimeToFirstByteMs : 28 ms
- OriginResponseDurationMs : 0 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 0
lower tier エッジがキャッシュを返しているため CacheTieredFill : false
、UpperTierColoID : 0
となり、EdgeTimeToFirstByteMs
は 470 ms から 28 ms へと激減しました。
ヨーロッパから日本オリジンにアクセス時の、キャッシュ状態別のHTTPレスポンスヘッダーとCloudflareリクエストログを整理します。
日本から日本オリジンにアクセス
続いて、オリジンと同じ東京からアクセスしてみましょう。
オリジンの前段に Upper Tier DCが待ち構えており、日本エリアから初めてリクエストしても、ドイツからのリクエスト時に作成されたキャッシュを利用できることを確認します。
HTTP/2 200 date: Tue, 24 May 2022 12:53:09 GMT content-type: application/json content-length: 18 x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0 last-modified: Tue, 24 May 2022 12:50:51 GMT cf-cache-status: HIT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 71062c2afcb40b93-NRT alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
Tiered Cacheの効果で、東京からのアクセスは初めてにもかかわらずキャッシュヒットしていますが、 age レスポンスヘッダーがありません。
- CacheCacheStatus : hit
- CacheTieredFill : true
- OriginIP :
- EdgeServerIP :
- EdgeTimeToFirstByteMs : 339 ms
- OriginResponseDurationMs : 3 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 382
CacheCacheStatus : hit
、CacheTieredFill : true
、UpperTierColoID : 382
から、 upper tier がキャッシュを返したことがわかります。
lower tierと upper tier が至近距離のためか、OriginResponseDurationMs
はわずか 3 ms です。
もう一度アクセスします。
HTTP/2 200 date: Tue, 24 May 2022 12:53:16 GMT content-type: application/json content-length: 18 x-amzn-requestid: 1166e998-7214-4682-b544-5d9c0a129a1e x-amzn-trace-id: root=1-628cd4ab-5b2beafd171e826e1f07157f;sampled=0 cf-cache-status: HIT age: 145 last-modified: Tue, 24 May 2022 12:50:51 GMT accept-ranges: bytes expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" server: cloudflare cf-ray: 71062c577c8620c5-NRT alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
- CacheCacheStatus : hit
- CacheTieredFill : false
- OriginIP :
- EdgeServerIP :
- EdgeTimeToFirstByteMs : 29 ms
- OriginResponseDurationMs : 0 ms
- OriginResponseHeaderReceiveDurationMs : 0 ms
- UpperTierColoID : 0
lower tier エッジがキャッシュを返しているため CacheTieredFill : false
、UpperTierColoID : 0
となり、
EdgeTimeToFirstByteMs
は 339 ms から 29 ms へと激減しました。
キャッシュ状態によるリクエストログ・レスポンスヘッダーの違い
レスポンスヘッダーの読み方
cf-cache-status | age | |
---|---|---|
[tiered cache]エッジでキャッシュヒット | HIT | 数字 |
[tiered cache]upper tierでキャッシュヒット | HIT | N/A |
[tiered cache]キャッシュミスし | MISS | N/A |
[非tiered cache]キャッシュミス | MISS | N/A |
Cloudflare キャッシュログの読み方
Cloudflareのログの Tiered Cacheに関連するフィールドをキャッシュ状況に応じて整理します。
CacheCacheStatus | CacheTieredFill | EdgeServerIP | EdgeTimeToFirstByteMs | OriginResponseDurationMs | OriginResponseHeaderReceiveDurationMs | UpperTierColoID | |
---|---|---|---|---|---|---|---|
[tiered cache]エッジでキャッシュヒット | hit | false | ブランク | 実測値 | 0 | 0 | 0 |
[tiered cache]upper tierでキャッシュヒットしエッジでキャッシュ化 | hit | true | ブランク | 実測値 | 0 | 0 | upper tier ID |
[tiered cache]キャッシュミスしupper tierでキャッシュ化 | miss | false | upper tierのIP | 実測値 | 実測値 | 実測値 | upper tier ID |
[非tiered cache]キャッシュミスしエッジでキャッシュ化 | miss | false | エッジのIP | 実測値 | 実測値 | 実測値 | 0 |
まとめ
CDNを効率的に使うには、キャッシュをヒットさせることが大事です。
そのようなアプローチの一つとして、Cloudflare Tiered Cache を紹介しました。 キャッシュを階層・集約化することでキャッシュヒット率が向上し、CDNとオリジン間の通信も減ります。
Tiered Cacheはあくまでも一時的なキャッシュのため、eviction/expireでキャッシュが削除されると、オリジンへのアクセスが発生します。 この欠点を補完し、キャッシュヒット率をさらに高めるソリューションとして、Cloudflare Cache Reserve というサービスがクローズド・ベータで提供されています。
Introducing Cache Reserve: massively extending Cloudflare’s cache
Cache Reserveを利用すると、キャッシュ化可能なコンテンツはオリジンから Cloudflare R2ストレージ(エッジ向けAmazon S3のようなもの)にプッシュされ、キャッシュミス時にはR2からコンテンツ配信されます。
キャッシュヒット率をさらに高め、R2はエグレス料金が無料のため、配信コストを抑えることが期待できます。
配信コンテンツによっては、R2のストレージコストを考慮しても、Cache Reserveが最適なソリューションとなります。